Telegram Group & Telegram Channel
⚙️ `[EnumeratorCancellation]` в C# — критически важный атрибут для корректной отмены в `IAsyncEnumerable`

В .NET асинхронные итераторы (`IAsyncEnumerable<T>`) стали мощным инструментом для потоковой обработки данных. Но если вы используете CancellationToken без специального атрибута [EnumeratorCancellation], ваш код может вести себя некорректно и утекать ресурсы. Разберёмся подробно.

⚠️ Проблема: токен есть, но он бесполезен

Допустим, вы пишете такой метод:


public async IAsyncEnumerable<string> FetchItems(CancellationToken cancellationToken)
{
foreach (var id in ids)
{
var item = await GetDataAsync(id);
yield return item;
}
}


Выглядит нормально, но есть подвох: при отмене токен не передаётся в `MoveNextAsync()`, то есть итерация может продолжаться, даже если вызвавшая сторона уже вызвала cancellationToken.Cancel().

💣 Последствия

• Фоновая загрузка продолжается после отмены
• Зависшие соединения, неосвобождённые ресурсы
• Непредсказуемое поведение в await foreach
• Сложные баги и плохая отзывчивость приложений

Решение: [EnumeratorCancellation]

Правильно будет вот так:


public async IAsyncEnumerable<string> FetchItems(
[EnumeratorCancellation] CancellationToken cancellationToken)
{
await foreach (var item in LoadFromDb().WithCancellation(cancellationToken))
{
cancellationToken.ThrowIfCancellationRequested();
yield return item;
}
}


📌 Атрибут [EnumeratorCancellation] сообщает компилятору, что токен должен быть передан в реализацию `MoveNextAsync()` итератора. Без этого атрибута токен проигнорируется.

🧪 Как проверить


var cts = new CancellationTokenSource();
await foreach (var item in FetchItems(cts.Token))
{
if (item == "stop") cts.Cancel();
}


Если метод реализован без [EnumeratorCancellation], цикл может не остановиться.
Если с атрибутом — отмена сработает как положено, и итерация завершится немедленно.

🛠 Best Practices

Всегда используйте [EnumeratorCancellation], если метод IAsyncEnumerable<T> принимает CancellationToken
Внутри итератора:
- Вызывайте ThrowIfCancellationRequested()
- Оборачивайте вложенные await foreach или асинхронные методы в .WithCancellation(token)
Не используйте токен «для галочки» — он должен влиять на поведение итератора
Добавляйте юнит‑тесты на отмену, особенно если вы работаете с I/O, API или базами данных

📎 Заключение

Асинхронные итераторы — мощь. Но без [EnumeratorCancellation] ваш токен отмены просто не работает. И это не очевидно, пока вы не столкнётесь с багом, когда ресурсы не освобождаются, или цикл не завершается.

Одна строка — и вы защищены:


[EnumeratorCancellation] CancellationToken token


📚 Источник: https://bartwullems.blogspot.com/2025/04/asyncenumerable-in-c-importance-of.html

🧠 Если ты пишешь на C# и используешь IAsyncEnumerable — знай: токен без атрибута = фейковая отмена.


📌 Читать

@csharp_1001_notes



tg-me.com/csharp_1001_notes/685
Create:
Last Update:

⚙️ `[EnumeratorCancellation]` в C# — критически важный атрибут для корректной отмены в `IAsyncEnumerable`

В .NET асинхронные итераторы (`IAsyncEnumerable<T>`) стали мощным инструментом для потоковой обработки данных. Но если вы используете CancellationToken без специального атрибута [EnumeratorCancellation], ваш код может вести себя некорректно и утекать ресурсы. Разберёмся подробно.

⚠️ Проблема: токен есть, но он бесполезен

Допустим, вы пишете такой метод:


public async IAsyncEnumerable<string> FetchItems(CancellationToken cancellationToken)
{
foreach (var id in ids)
{
var item = await GetDataAsync(id);
yield return item;
}
}


Выглядит нормально, но есть подвох: при отмене токен не передаётся в `MoveNextAsync()`, то есть итерация может продолжаться, даже если вызвавшая сторона уже вызвала cancellationToken.Cancel().

💣 Последствия

• Фоновая загрузка продолжается после отмены
• Зависшие соединения, неосвобождённые ресурсы
• Непредсказуемое поведение в await foreach
• Сложные баги и плохая отзывчивость приложений

Решение: [EnumeratorCancellation]

Правильно будет вот так:


public async IAsyncEnumerable<string> FetchItems(
[EnumeratorCancellation] CancellationToken cancellationToken)
{
await foreach (var item in LoadFromDb().WithCancellation(cancellationToken))
{
cancellationToken.ThrowIfCancellationRequested();
yield return item;
}
}


📌 Атрибут [EnumeratorCancellation] сообщает компилятору, что токен должен быть передан в реализацию `MoveNextAsync()` итератора. Без этого атрибута токен проигнорируется.

🧪 Как проверить


var cts = new CancellationTokenSource();
await foreach (var item in FetchItems(cts.Token))
{
if (item == "stop") cts.Cancel();
}


Если метод реализован без [EnumeratorCancellation], цикл может не остановиться.
Если с атрибутом — отмена сработает как положено, и итерация завершится немедленно.

🛠 Best Practices

Всегда используйте [EnumeratorCancellation], если метод IAsyncEnumerable<T> принимает CancellationToken
Внутри итератора:
- Вызывайте ThrowIfCancellationRequested()
- Оборачивайте вложенные await foreach или асинхронные методы в .WithCancellation(token)
Не используйте токен «для галочки» — он должен влиять на поведение итератора
Добавляйте юнит‑тесты на отмену, особенно если вы работаете с I/O, API или базами данных

📎 Заключение

Асинхронные итераторы — мощь. Но без [EnumeratorCancellation] ваш токен отмены просто не работает. И это не очевидно, пока вы не столкнётесь с багом, когда ресурсы не освобождаются, или цикл не завершается.

Одна строка — и вы защищены:


[EnumeratorCancellation] CancellationToken token


📚 Источник: https://bartwullems.blogspot.com/2025/04/asyncenumerable-in-c-importance-of.html

🧠 Если ты пишешь на C# и используешь IAsyncEnumerable — знай: токен без атрибута = фейковая отмена.


📌 Читать

@csharp_1001_notes

BY C# 1001 notes


Warning: Undefined variable $i in /var/www/tg-me/post.php on line 283

Share with your friend now:
tg-me.com/csharp_1001_notes/685

View MORE
Open in Telegram


C 1001 notes Telegram | DID YOU KNOW?

Date: |

Look for Channels Online

You guessed it – the internet is your friend. A good place to start looking for Telegram channels is Reddit. This is one of the biggest sites on the internet, with millions of communities, including those from Telegram.Then, you can search one of the many dedicated websites for Telegram channel searching. One of them is telegram-group.com. This website has many categories and a really simple user interface. Another great site is telegram channels.me. It has even more channels than the previous one, and an even better user experience.These are just some of the many available websites. You can look them up online if you’re not satisfied with these two. All of these sites list only public channels. If you want to join a private channel, you’ll have to ask one of its members to invite you.

The global forecast for the Asian markets is murky following recent volatility, with crude oil prices providing support in what has been an otherwise tough month. The European markets were down and the U.S. bourses were mixed and flat and the Asian markets figure to split the difference.The TSE finished modestly lower on Friday following losses from the financial shares and property stocks.For the day, the index sank 15.09 points or 0.49 percent to finish at 3,061.35 after trading between 3,057.84 and 3,089.78. Volume was 1.39 billion shares worth 1.30 billion Singapore dollars. There were 285 decliners and 184 gainers.

C 1001 notes from ru


Telegram C# 1001 notes
FROM USA